<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8">
        <title>操作元素</title>
        <style>
            .buttons { border: 1px solid blue; margin: 15px auto; }
            .buttons>button { margin: 10px 0 10px 10px; }

            .wrapper { border: 1px solid green; margin: 15px auto; }
            .wrapper>header,
            .wrapper>footer { border: 1px solid gray; margin: 10px; background: #dfdfdf; }
            .target { border: 1px solid red; margin: 10px; }
            .target p { margin: 0; }
            .target>*:nth-child(2n) { background: #f4f4f4; }
            .target>*:nth-child(2n+1) { background: #ffff00; }

            div.new { background: purple; margin: 10px; color: #fff; }
        </style>
    </head>
    <body>
        <h1>操作元素</h1>

        <div class="buttons">
            <button type="button" class="prepend">在内部最前方插入元素</button>
            <button type="button" class="append">在内部末尾追加元素</button>
            <button type="button" class="replace-children">为元素替换子元素们(实验)</button>
            <button type="button" class="before">在外部最前方插入元素(实验)</button>
            <button type="button" class="after">在外部后方插入元素</button>
            <button type="button" class="remove">删除元素</button>
            <button type="button" class="replace-with">将元素替换指定的元素(实验)</button>
        </div>

        <div class="wrapper">
            <header>大老大</header>
            <div class="target">
                <div>小老大</div>
                <p>我是个段落</p>
                <div>小老幺</div>
            </div>
            <footer>大老幺</footer>
        </div>

        <div class="wrapper">
            <button type="button" class="attribute set">设置属性</button>
            <button type="button" class="attribute remove">删除属性</button>
            <button type="button" class="attribute toggle">切换布尔值属性的状态</button>
            <button type="button" class="attribute get">获取属性</button>
            <br>
            <input class="username">
        </div>

        <div class="wrapper">
            <p>Element的原型属性</p>
            <ul>
                <li>Element.prototype.before( node | DOMString ) 在元素外部前方插入新元素或DOMString 【实验功能】</li>
                <li>Element.prototype.after( node | DOMString ) 在元素外部后方插入新元素或DOMString</li>
                <li>Element.prototype.prepend( node | DOMString ) 在元素内部头部插入新元素或DOMString</li>
                <li>Element.prototype.append( node | DOMString ) 在元素内部末尾追加新元素或DOMString</li>
                <li>Element.prototype.remove() 删除当前元素</li>
                <li>Element.prototype.replaceChildren([node | DOMString]) 用参数替换当前元素的子元素们 【实验功能】</li>
                <li>Element.prototype.replaceWith( node | DOMString ) 将当前元素替换指定的元素 【实验功能】</li>
                <li>Element.prototype.setAttribute(name, value) 为元素设置属性(新增或替换)</li>
                <li>Element.prototype.removeAttribute(name) 根据属性名删除属性</li>
                <li>Element.prototype.toggleAttribute(name[,force]) 切换当前元素的某个布尔值属性的状态</li>
                <li>scroll()</li>
                <li>scrollBy()</li>
                <li>scrollTo()</li>
                <li>scrollIntoView()</li>
            </ul>
        </div>

        <div class="wrapper">
            <p>参考文档</p>
            <ul>
                <li>
                    <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Element/append">Node.prototype.appendChild与Element.prototype.append区别</a>
                </li>
            </ul>
        </div>

        <script>
            // 定义一个根据选择器获取页面上匹配选择器首个元素的方法
            function find(selector) {
                return document.querySelector(selector);
            }

            // 定义一个用于为元素绑定点击事件监听器的函数
            function bind(element, handler){
                element.addEventListener('click', handler, false);
            }

            const prependBtn = find('.buttons>.prepend');
            bind(prependBtn, function(){
                const t = find('.target');
                let node = document.createElement('div');
                node.innerHTML = new Date().toISOString();
                t.prepend( node );
            });

            const appendBtn = find('.buttons>.append');
            bind(appendBtn, function(){
                const t = find('.target');
                let node = document.createElement('div');
                node.innerHTML = new Date().toISOString();
                t.append( node );
            });

            const replaceChildrenBtn = find('.buttons>.replace-children');
            bind(replaceChildrenBtn, function(){
                const t = find('.target');
                let nodes = [];
                for(let i = 1 ; i <= 3 ; i++ ){
                    let e = document.createElement('div');
                    e.innerHTML = i;
                    nodes.push(e);
                }
                // 将数组展开后依次传递给 replaceChildren 函数
                t.replaceChildren(...nodes);
            });

            const beforeBtn = find('.buttons>.before');
            bind(beforeBtn, function(){
                const t = find('.target');
                let node = document.createElement('div');
                node.classList.add('new');
                node.innerHTML = new Date().toISOString();
                t.before( node );
            });

            const afterBtn = find('.buttons>.after');
            bind(afterBtn, function(){
                const t = find('.target');
                let node = document.createElement('div');
                node.classList.add('new');
                node.innerHTML = new Date().toISOString();
                t.after( node );
            });

            const removeBtn = find('.buttons>.remove');
            bind(removeBtn, function(){
                const t = find('.target');
                if( t ) {
                    t.remove();
                }
            });

            const replaceWithBtn = find('.buttons>.replace-with');
            bind(replaceWithBtn, function(){
                const t = find('.target');
                let nodes = [];
                for(let i = 1 ; i <= 3 ; i++ ){
                    let e = document.createElement('div');
                    e.classList.add('new');
                    e.innerHTML = i;
                    nodes.push(e);
                }
                // 将数组展开后依次传递给 replaceWith 函数
                t.replaceWith(...nodes);
            });
        
            const setAttrBtn = find('.attribute.set');
            bind(setAttrBtn, function(){
                const t = find('input.username');
                t.setAttribute('type', 'text');
                t.setAttribute('placeholder', '请输入用户名');
                // 以 data- 为前缀的属性是 HTML5 新增的 "自定义数据属性"
                t.setAttribute('data-user-id', '12345');
            });

            const removeAttrBtn = find('.attribute.remove');
            bind(removeAttrBtn, function(){
                const t = find('input.username');
                t.removeAttribute('type');
                t.removeAttribute('placeholder');
            });

            const toggleAttrBtn = find('.attribute.toggle');
            bind(toggleAttrBtn, function(){
                const t = find('input.username');
                console.log( t.toggleAttribute('disabled') );
            });

            const getAttrBtn = find('.attribute.get');
            bind(getAttrBtn, function(){
                const t = find('input.username');
                console.log( t.getAttribute( 'data-user-id' ));
                // 以 data- 为前缀的属性统统被存放在 dataset 中
                console.log( t.dataset );
                // data-user-id 去掉 data- 前缀得到 user-id,
                // user-id 去掉所有`-`并将所有`-`之后的字符大写  得到 userId
                console.log( t.dataset.userId );
            });

        </script>
    </body>
</html>

